package com.example.demo.controller;

import com.example.demo.entity.Cart;
import com.example.demo.entity.CartPage;
import com.example.demo.entity.CookieCart;
import com.example.demo.service.CartService;
import com.example.demo.service.IdGenerator;
import com.example.demo.util.KafkaUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@Api(value = "购物车controller",tags = "Redis-Cookie购物车接口（用户未登录）")
@RequestMapping("/cart/cookieCart")
public class CookieCartController {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private CartService cartService;

    @Autowired
    private KafkaUtils kafkaUtils;

    //设置前缀
    public static final String COOKIE_KEY = "cart:cookie:";

    //添加购物车
    @ResponseBody
    @RequestMapping(value = "/addCart", method = RequestMethod.POST)
    @ApiOperation(value = "添加购物车",tags = {"Redis-Cookie购物车接口（用户未登录）"},httpMethod = "POST")
    @ApiImplicitParams({@ApiImplicitParam(name = "menuId",value = "菜单id",dataType = "Long",paramType = "query"),
            @ApiImplicitParam(name = "number",value = "数量",dataType = "int",paramType = "query")})
    public void addCart(@RequestParam("menuId") Long menuId,
                        @RequestParam("number") Integer number){
        String cartId = this.getCookiesCartId();
        String key = COOKIE_KEY + cartId;
        Boolean hasKey = redisTemplate.opsForHash().getOperations().hasKey(key);
        if (hasKey){
            this.redisTemplate.opsForHash().put(key, menuId.toString(), number);
        }else{
            this.redisTemplate.opsForHash().put(key, menuId.toString(), number);
            this.redisTemplate.expire(key, 90, TimeUnit.DAYS);
        }

    }

    //修改购物车
    @ResponseBody
    @RequestMapping(value = "/updateCart", method = RequestMethod.POST)
    @ApiOperation(value = "更新购物车菜品数",tags = {"Redis-Cookie购物车接口（用户未登录）"},httpMethod = "POST")
    @ApiImplicitParams({@ApiImplicitParam(name = "menuId",value = "菜单id",dataType = "Long",paramType = "query"),
            @ApiImplicitParam(name = "number",value = "数量",dataType = "int",paramType = "query")})
    public void updateCart(@RequestParam("menuId") Long menuId,
                           @RequestParam("number") Integer number){
        String cartId = this.getCookiesCartId();
        String key = COOKIE_KEY + cartId;
        this.redisTemplate.opsForHash().put(key, menuId.toString(), number);
    }

    //删除菜品
    @ResponseBody
    @RequestMapping(value = "/delCart",method = RequestMethod.POST)
    @ApiOperation(value = "删除菜品",tags = {"Redis-Cookie购物车接口（用户未登录）"},httpMethod = "POST")
    @ApiImplicitParam(name = "menuId",value = "菜单id",dataType = "Long",paramType = "query")
    public void delCart(@RequestParam("menuId") Long menuId){
        String cartId = this.getCookiesCartId();
        String key = COOKIE_KEY + cartId;
        this.redisTemplate.opsForHash().delete(key, menuId.toString());
    }


    @RequestMapping(value = "/findAll",method = RequestMethod.GET)
    @ApiOperation(value = "查询购物车",tags = {"Redis-Cookie购物车接口（用户未登录）"},httpMethod = "GET")
    public CartPage findAll(){
        String cartId = this.getCookiesCartId();
        String key = COOKIE_KEY + cartId;

        CartPage<CookieCart> cartPage = new CartPage();
        //查购物车的总数
        long size = this.redisTemplate.opsForHash().size(key);
        cartPage.setCount((int) size);

        //查询购物车的所有商品
        Map<String, Integer> map = this.redisTemplate.opsForHash().entries(key);
        List<CookieCart> cartList = new ArrayList<>();
        for (Map.Entry<String, Integer>entry : map.entrySet()){
            CookieCart cart = new CookieCart();
            cart.setMenuId(Long.parseLong(entry.getKey()));
            cart.setAmount(entry.getValue());
            cartList.add(cart);
        }
        cartPage.setCartList(cartList);
        return cartPage;

    }

    /*
     * 合并购物车
     * 把cookie中的购物车合并到登录用户的购物车当中
     */

    @ResponseBody
    @RequestMapping(value = "/mergeCart",method = RequestMethod.PUT)
    @ApiOperation(value = "合并购物车",tags = {"Redis-Cookie购物车接口（用户未登录）"},httpMethod = "PUT")
    @ApiImplicitParam(name = "userId",value = "用户id",dataType = "Long",paramType = "query")
    public void mergeCart(@RequestParam("userId") Long userId){
        //第一步：提取未登录用户的cookie的购物车数据
        String cartId = this.getCookiesCartId();
        String keyCookie = COOKIE_KEY + cartId;
        Map<String, Integer> map = this.redisTemplate.opsForHash().entries(keyCookie);

        //第二步：把cookie中的购物车合并到登录用户的购物车
        String keyUser = "cart:user:" + userId;
        this.redisTemplate.opsForHash().putAll(keyUser, map);

        //第三步：删除Redis未登录的用户cookies的购物车数据
        this.redisTemplate.delete(keyCookie);


        //第四步：删除未登录用户cookies的cartId
        Cookie cookie = new Cookie("cartId",null);
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        //第五步、数据库同步
        //TODO 发 rabbitmq 出去
        for (Map.Entry<String, Integer>entry : map.entrySet()){
            //存入数据库请求参数
            String sqlMessage = "CartAdd,"+userId+","+ Long.parseLong(entry.getKey()) +","+entry.getValue();
            //TODO 发 rabbitmq 出去
            kafkaUtils.sendMessage("topic1",sqlMessage);
        }
    }

    //获取cookies
    public String getCookiesCartId(){
        //第一步：先检查cookies是否有cartId
        Cookie[] cookies = request.getCookies();
        if (cookies != null){
            for (Cookie cookie : cookies){
                if (cookie.getName().equals("cartId")){
                    return cookie.getValue();
                }
            }
        }

        //第二步: cookies中若没有cartId，直接生成全局id,并设置到cookie里面
        //生成全局唯一id
        Long id = this.idGenerator.incrementId();
        //将cartId设置到cookie里面去
        Cookie cookie = new Cookie("cartId", String.valueOf(id));
        response.addCookie(cookie);
        return id + "";
    }



}
